<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator'
import { CreateElement } from 'vue'
import { saveAs } from 'file-saver'
import { $url } from '@/utils'

interface DownloadParams {
  [key: string]: any
}

@Component({
  name: 'FileDownload'
})
export default class extends Vue {
  // download URL
  @Prop({ type: String, required: true })
  private action!: string
  // HTTP request method
  @Prop({
    type: String,
    required: false,
    default: 'post',
    validator: v => ['post', 'get'].includes(v)
  })
  private method!: string
  // HTTP request params
  @Prop({ type: Object, required: false, default: () => null })
  private params!: DownloadParams
  // button text
  @Prop({ type: String, required: false, default: 'download' })
  private placeholder!: string

  private loading = false

  private handleDownload (): void {
    this.loadingChange()
    if (this.method === 'post') {
      this.downloadPost()
    } else {
      this.downloadGet()
    }
  }
  private loadingChange (): void {
    const vm = this
    vm.loading = true
    setTimeout(() => {
      vm.loading = false
    }, 1500)
  }
  private downloadGet (): void {
    saveAs($url(this.action, this.params))
  }
  private downloadPost (): void {
    let oF = document.createElement('FORM')
    oF.setAttribute('action', $url(this.action))
    oF.setAttribute('method', this.method)
    oF.setAttribute('target', '_blank')
    oF.setAttribute('style', 'display:none;')

    for (const key in this.params) {
      let oInput = document.createElement('INPUT')
      oInput.setAttribute('type', 'hidden')
      oInput.setAttribute('name', key)
      oInput.setAttribute('value', this.params[key])

      oF.appendChild(oInput)
    }

    document.body.appendChild(oF)
    ;(oF as HTMLFormElement).submit()
    document.body.removeChild(oF)
  }

  render (h: CreateElement) {
    return h(
      'el-button',
      {
        props: {
          type: 'primary',
          loading: this.loading,
          icon: 'el-icon-download'
        },
        on: {
          click: this.handleDownload
        }
      },
      this.placeholder
    )
  }
}
</script>
